/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.vo.*;
import org.springblade.modules.admin.mapper.MaintainCheckHistoryMapper;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.admin.vo.plan.store.ByWorkScoreInfoVo;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 点检内容历史记录 服务实现类
 *
 * @author BladeX
 * @since 2021-05-11
 */
@Service
@AllArgsConstructor
public class MaintainCheckHistoryServiceImpl extends BaseServiceImpl<MaintainCheckHistoryMapper, MaintainCheckHistory> implements IMaintainCheckHistoryService {

	@Autowired
	private IMaintainPlanContentService planContentService;
	@Autowired
	private IMaintainPlanContentUserService planContentUserService;
	@Autowired
	private IUserService userService;
	@Autowired
	private IMaintainSignService signService;
	@Autowired
	private IMaintainTemplateSceneRelationService templateSceneRelationService;
	@Autowired
	private IPlanCheckHistoryScoreService planCheckHistoryScoreService;

	@Override
	public List<PlanTemplateVO> getPlanWorkItem(Long planId, Long templateId, Integer isStore) {
		List<PlanTemplateVO> planCheckHistoryList = baseMapper.listPlanHistory(planId, templateId, isStore, AuthUtil.getTenantId());
		List<ByWorkScoreInfoVo> byWorkScoreInfo = planCheckHistoryScoreService.getByWorkScoreInfo(planId);
		Map<Long, List<ByWorkScoreInfoVo>> listMap = byWorkScoreInfo.stream().collect(Collectors.groupingBy(ByWorkScoreInfoVo::getCheckHistoryId));

		PlanTemplateVO planTemplateVO = new PlanTemplateVO();
		planTemplateVO.setTemplateId(-1L);
		planTemplateVO.setTemplateName("全部");
		planTemplateVO.setTemplateContentVOS(new ArrayList<>());
		for (PlanTemplateVO planTemplateVO1 : planCheckHistoryList) {
			List<PlanTemplateContentVO> templateContentVOS = planTemplateVO1.getTemplateContentVOS();
			//新增评分信息返回
			if (listMap.size() > 0) {
				for (PlanTemplateContentVO planTemplateContentVO : templateContentVOS) {
					List<ByWorkScoreInfoVo> voList = listMap.get(planTemplateContentVO.getCheckHistoryId());
					if (voList != null && voList.size() > 0) {
						planTemplateContentVO.setByWorkScoreInfoVos(voList);
					}
				}
			}
			planTemplateVO.getTemplateContentVOS().addAll(templateContentVOS);
		}
		planCheckHistoryList.add(0, planTemplateVO);
		planCheckHistoryList.forEach(e -> {
			e = disposePlanTemplateType(e, planId);
			e.setTemplateContentVOS(null);
		});
		return planCheckHistoryList;
	}

	@Override
	public HashMap<String, Object> selectPlanDetail(Long planId) {
		MaintainPlanContent maintainPlanContent = planContentService.getById(planId);
		List<MaintainPlanContentUser> planContentUsers = planContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, planId));
		planContentUsers = planContentUsers.stream().filter(e -> {
			String userName = userService.getById(e.getUserId()).getRealName();
			e.setUserName(userName);
			Integer userSignCount = signService.count(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId, e.getPlanId()).eq(MaintainSign::getUserId, e.getUserId()));
			e.setUserSignCount(userSignCount);
			if (maintainPlanContent.getStatus().equals(TaskStatusEnum.BY_FINISH.getStatus()) || maintainPlanContent.getStatus().equals(TaskStatusEnum.BY_SIGN.getStatus())) {
				int signCount = signService.count(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId, planId).eq(MaintainSign::getUserId, e.getUserId()));
				if (signCount > 0) {
					return true;
				}
			} else {
				return true;
			}
			return false;
		}).collect(Collectors.toList());

		HashMap<String, Object> planDetailMap = new HashMap<>(2);
		planDetailMap.put("planDate", maintainPlanContent.getPlanDate());
		planDetailMap.put("status", maintainPlanContent.getStatus());
		planDetailMap.put("statusName", TaskStatusEnum.getTaskName(maintainPlanContent.getTypeStatus(), maintainPlanContent.getStatus()));
		planDetailMap.put("users", planContentUsers);
		return planDetailMap;
	}

	@Override
	public void initTemplateSceneType() {
		List<MaintainCheckHistory> checkHistories = super.list();
		List<MaintainTemplateSceneRelation> templateSceneRelations = templateSceneRelationService.listAll();
		List<List<MaintainCheckHistory>> list = ListUtil.partition(checkHistories, 50);
		list.forEach(e -> {
			e.forEach(j -> {
				templateSceneRelations.forEach(k -> {
					if (k.getTemplateId().equals(j.getTemplateId())) {
						j.setTemplateSceneTypeId(k.getSceneTypeId());
						j.setTemplateSceneTypeName(k.getSceneTypeName());
					}
				});
			});
			super.updateBatchById(e);
		});
	}

	/**
	 * 封装模板分类及对应工作项
	 *
	 * @param planTemplateVO
	 * @return
	 */
	private PlanTemplateVO disposePlanTemplateType(PlanTemplateVO planTemplateVO, Long planId) {
		List<PlanTemplateContentVO> templateContentVOS = planTemplateVO.getTemplateContentVOS();
		List<PlanTemplateTypeVO> templateTypeVOS = getTypeZeroList(templateContentVOS);
		for (PlanTemplateContentVO t : templateContentVOS) {
			// 封装模板分类Tree
			List<String> tltIds = Func.toStrList(t.getTltIds());
			List<String> tltIdName = Func.toStrList("&&", t.getTltNames());
			if (tltIds.size() > 1) {
				for (int i = 1; i < tltIds.size(); i++) {
					templateTypeVOS = changeHistory(templateTypeVOS, Long.valueOf(tltIds.get(i)), tltIdName.get(i), Long.valueOf(tltIds.get(i - 1)));
				}
			}
		}
		// 封装对应工作项
		templateTypeVOS = changeHistoryContent(templateTypeVOS, templateContentVOS);
		templateTypeVOS.forEach(e -> {
			e = doCount(e, new HashMap<>());
		});
		planTemplateVO.setTemplateTypeVOS(templateTypeVOS);
		return planTemplateVO;
	}

	/**
	 * 封装任务历史数据分类Tree根节点
	 *
	 * @param templateContentVOS
	 * @return
	 */
	private List<PlanTemplateTypeVO> getTypeZeroList(List<PlanTemplateContentVO> templateContentVOS) {
		List<PlanTemplateTypeVO> planTemplateTypeVOS = templateContentVOS.stream().map(e -> {
			List<String> tltIds = Func.toStrList(e.getTltIds());
			List<String> tltIdName = Func.toStrList("&&", e.getTltNames());
			PlanTemplateTypeVO planTemplateTypeVO = new PlanTemplateTypeVO();
			planTemplateTypeVO.setTltId(Long.valueOf(tltIds.get(0)));
			planTemplateTypeVO.setTltName(tltIdName.get(0));
			planTemplateTypeVO.setTltParentId(0L);
			return planTemplateTypeVO;
		}).collect(Collectors.toList());
		planTemplateTypeVOS = planTemplateTypeVOS.stream().collect(Collectors.collectingAndThen(
			Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(e -> e.getTltId() + ";" + e.getTltName()))), ArrayList::new
		));
		return planTemplateTypeVOS;
	}

	/**
	 * 封装历史对应工作项分类数据
	 *
	 * @param planTemplateTypeVOS
	 * @param tltId
	 * @return
	 */
	private List<PlanTemplateTypeVO> changeHistory(List<PlanTemplateTypeVO> planTemplateTypeVOS, Long tltId, String tltName, Long parentId) {
		planTemplateTypeVOS.forEach(e -> {
			if (e.getTltId().equals(parentId)) {
				List<PlanTemplateTypeVO> children = e.getChildren();
				if (ObjectUtil.isEmpty(children)) {
					children = new ArrayList<>();
				}
				PlanTemplateTypeVO planTemplateTypeVO = new PlanTemplateTypeVO();
				planTemplateTypeVO.setTltId(tltId);
				planTemplateTypeVO.setTltName(tltName);
				planTemplateTypeVO.setTltParentId(parentId);
				children.add(planTemplateTypeVO);
				children = children.stream().collect(Collectors.collectingAndThen(
					Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(j -> j.getTltId() + ";" + j.getTltName()))), ArrayList::new
				));
				e.setChildren(children);
			} else {
				if (ObjectUtil.isNotEmpty(e.getChildren())) {
					changeHistory(e.getChildren(), tltId, tltName, parentId);
				}
			}
		});
		return planTemplateTypeVOS;
	}

	/**
	 * 封装历史记录对应工作项
	 *
	 * @param templateTypeVOS 分类tree集合
	 * @return
	 */
	private List<PlanTemplateTypeVO> changeHistoryContent(List<PlanTemplateTypeVO> templateTypeVOS, List<PlanTemplateContentVO> templateContentVOS) {
		templateTypeVOS.forEach(e -> {
			if (ObjectUtil.isEmpty(e.getChildren())) {
				templateContentVOS.forEach(j -> {
					List<String> tltIds = Func.toStrList(j.getTltIds());
					if (e.getTltId().equals(Long.valueOf(tltIds.get(tltIds.size() - 1)))) {
						List<PlanTemplateContentVO> planTemplateContentVOS = e.getPlanTemplateContentVOS();
						if (ObjectUtil.isEmpty(planTemplateContentVOS)) {
							planTemplateContentVOS = new ArrayList<>();
						}
						planTemplateContentVOS.add(j);
						e.setPlanTemplateContentVOS(planTemplateContentVOS);
					}
				});
			} else {
				changeHistoryContent(e.getChildren(), templateContentVOS);
			}
		});
		return templateTypeVOS;
	}

	/**
	 * 树形结构展示的某个节点的统计数值=所有子节点工作项数量总和
	 *
	 * @param root
	 * @param result
	 * @return
	 */
	public static PlanTemplateTypeVO doCount(PlanTemplateTypeVO root, Map<String, Object> result) {
		int count = 0;
		List<PlanTemplateTypeVO> list = root.getChildren();
		if (ObjectUtil.isEmpty(list)) {
			count = root.getPlanTemplateContentVOS().size();
			root.setWorkItemCount(count);
			return root;
		}

		for (PlanTemplateTypeVO child : list) {
			//统计子节点的孩子总数
			int cur_cnt = doCount(child, result).getWorkItemCount();
			result.put(String.valueOf(child.getTltId()), cur_cnt);
			count += cur_cnt;
			root.setWorkItemCount(count);
		}

		//返回前记录当前节点的统计个数
		result.put(String.valueOf(root.getTltId()), count);
		return root;
	}

//	private final ElevatorService elevatorService;
//	private final IMaintainPlanConfigService planConfigService;
//	private final IMaintainTemplateContentService templateContentService;
//	private final IMaintainTemplateLocationTypeService locationTypeService;
//	private final MaintainPlanContentMapper maintainPlanContentMapper;
//	private final MaintainPlanSpecialConfigMapper specialConfigMapper;
//	private final MaintainCheckSpecialHistoryService specialHistoryService;
//
//	@Override
//	public IPage<MaintainCheckHistoryVO> selectMaintainCheckHistoryPage(IPage<MaintainCheckHistoryVO> page, MaintainCheckHistoryVO maintainCheckHistory) {
//		return page.setRecords(baseMapper.selectMaintainCheckHistoryPage(page, maintainCheckHistory));
//	}
//
//	@Override
//	public List<MaintainTemplateLocationTypeVO> specialTypeDetail(Long planId) {
//		MaintainPlanContent planContent = maintainPlanContentMapper.selectById(planId);
//		if (planContent == null) {
//			throw new ServiceException("未找到相关保养计划！");
//		}
//		List<MaintainTemplateLocationTypeVO> locationTypes = locationTypeService.getLocationTypes(planId);
//		if (locationTypes == null) {
//			return null;
//		}
//
//		for (MaintainTemplateLocationTypeVO locationType : locationTypes) {
//			HashMap<String,Object> resultMap = new HashMap<>(6);
//			HashMap<String,Object> buildingData = maintainPlanContentMapper.selectBuildingData(planId);
//			resultMap.putAll(buildingData);
//			resultMap.put("status",planContent.getStatus());
//			MaintainPlanSpecialConfig specialConfig = specialConfigMapper.selectOne(Wrappers.<MaintainPlanSpecialConfig>lambdaQuery().eq(MaintainPlanSpecialConfig::getPlanId,planId));
//			if(planContent.getStatus().equals(MaintainPlanContentStatusEnum.DISABLE.getId())){
//				List<MaintainTemplateContent> templateContents = templateContentService.list(Wrappers.<MaintainTemplateContent>lambdaQuery()
//					.eq(MaintainTemplateContent::getTemplateId,specialConfig.getTemplateId()).like(MaintainTemplateContent::getLocationTypeIds,locationType.getId()).orderByDesc(MaintainTemplateContent :: getId));
//				List<SpecialHistoryVO> specialHistoryVOS = new ArrayList<>();
//				for (MaintainTemplateContent templateContent : templateContents) {
//					SpecialHistoryVO historyVO = new SpecialHistoryVO();
//					BeanUtils.copyProperties(templateContent, historyVO);
//					specialHistoryVOS.add(historyVO);
//				}
//				locationType.setTotal(templateContents.size());
//				locationType.setSpecialHistories(specialHistoryVOS);
//			}else {
//				List<SpecialHistoryVO> specialHistoryVOS = specialHistoryService.selectByPlan(planId,locationType.getId());
//				locationType.setTotal(specialHistoryVOS.size());
//				locationType.setSpecialHistories(specialHistoryVOS);
//			}
//		}
//
//		return locationTypes;
//	}
}
